#include "udp_dispatcher.h"
#include <random>

using namespace VLRTSP;


/**
 * @Author: CimZzz
 * @Date: 2022-01-14 11:45:35
 * 
 * 构造函数
 * @param id 媒体分发器 Id
 * @param rtpSendPoint RTP 发送端口 / Channel
 * @param rtcpSendPoint RTCP 发送端口 / Channel
 * @param mediaSource 媒体资源
 */
UDPDispatcher::UDPDispatcher(
	std::string ip,
	uint32_t id,
	uint32_t rtpSendPoint,
	uint32_t rtcpSendPoint,
	std::shared_ptr<MediaSource> mediaSource
): MediaDispatcher(id, rtpSendPoint, rtcpSendPoint, mediaSource), ip(ip) {
}


/**
 * @Author: CimZzz
 * @Date: 2022-01-14 11:46:07
 * 
 * 析构函数
 */
UDPDispatcher::~UDPDispatcher() {

}


/**
 * @Author: CimZzz
 * @Date: 2022-01-14 16:53:06
 * 
 * 初始化数据分发器
 * @return 如果初始化成功返回 true
 */
bool UDPDispatcher::init() {
	std::random_device rd;
	for(int i = 0 ; i <= 10 ; i ++) {
		// 循环 10 次寻找可用端口
		if(i == 10) {
			return false;
		}
		uint16_t rtpPort = rd() & 0xFFFE;
		uint16_t rtcpPort = rtpPort + 1;
		if(this->rtpSocket.bind(rtpPort) && this->rtcpSocket.bind(rtcpPort)) {
			break;
		}
		this->rtpSocket.close();
		this->rtcpSocket.close();
	}
	return true;
}

/**
 * @Author: CimZzz
 * @Date: 2022-01-14 17:00:32
 * 
 * 获取服务端 RTP 端口号
 * @return 服务端 RTP 端口号
 */
uint16_t UDPDispatcher::getServerRTPPort() {
	return this->rtpSocket.getBindPort();
}

/**
 * @Author: CimZzz
 * @Date: 2022-01-14 17:00:51
 * 
 * 获取服务器 RTCP 端口号
 * @return 服务器 RTCP 端口号
 */
uint16_t UDPDispatcher::getServerRTCPPort() {
	return this->rtcpSocket.getBindPort();
}

/**
 * @Author: CimZzz
 * @Date: 2022-01-14 11:43:10
 * 
 * 消息队列回调函数
 * @param sendBuffer 待发送的 RTP 帧
 */
void UDPDispatcher::onRecvSendBuffer(std::shared_ptr<RTPFrame>& sendBuffer) {
	if(rtpSocket.write(sendBuffer.get()->buffer.get(), this->ip, this->getRTPStartPoint())) {
		VL_PRINT("发送 UDP 数据 ip: %s:%u, 数据长度: %u", this->ip.c_str(), this->getRTPStartPoint(), sendBuffer.get()->buffer.get()->getBufferLength())
	}
}